home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / dakit / animio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-03  |  12.8 KB  |  531 lines

  1. /*----------------------------------------------------------------------*/
  2. /*                                                                        */
  3. /*            animio.c  -  Page-flip animation-- file io code.            */
  4. /*                                                                        */
  5. /*----------------------------------------------------------------------*/
  6.  
  7.  
  8. #include "main.h"
  9. #include "anim.h"        /* FIRST_FRAME_N */
  10. #include "dpiff.h"
  11. #include "dialogmg.h"    /* for LIST definition */
  12. #include "string.h"
  13. #include <sys\types.h>
  14. #include <sys\stat.h>
  15.  
  16. extern SHORT curDepth;
  17. extern UWORD *ytable;
  18. extern BITMAP hidbm;
  19. extern AnimOb curAnimBr;
  20. extern SHORT curfps, nPages, curPage;
  21. extern animProcHandle *animOps;
  22.  
  23. #define local static
  24.  
  25. BOOL isAnimBrIO = NO;
  26.  
  27. #if 0
  28. SHORT saveFrameNum;
  29. SHORT saveStart, nSave, loadStart = 0;
  30.  
  31. #endif
  32.  
  33. typedef struct IntuiMessage IMsg;
  34.  
  35.  
  36. DPAnimChunk dpAnimChnk;
  37.  
  38. #if 0
  39. #define AnimOp(N) (*animOps[N])()
  40. #endif
  41.  
  42. FreeDelta(register Delta * del)
  43. {
  44.     register int p;
  45.  
  46.     for (p = 0; p < curDepth; p++) {
  47.         FP_SEG(del->plane[p]) = SFree(FP_SEG(del->plane[p]));
  48.     }
  49. }
  50.  
  51.  
  52. /*--------------------------------------------------------------*/
  53. /* Read In ANIM iff files                                        */
  54. /*--------------------------------------------------------------*/
  55.  
  56.  
  57. #ifdef DBGDLTA
  58. BOOL dbgdlta = YES;
  59.  
  60. #endif
  61.  
  62.  
  63. /*--------------------------------------------------------------*/
  64. /*- Read in a DPAN chunk                              -----------*/
  65. /*--------------------------------------------------------------*/
  66. IFFP GetDPAnimChunk(context)
  67. GroupContext *context;
  68. {
  69.     IFFP iffp = IFFReadBytes(
  70.               context, (BYTE *) & dpAnimChnk, (LONG) sizeof(DPAnimChunk));
  71.  
  72.     ByteFlipAnimChunk(&dpAnimChnk);
  73. #ifdef DBGDLTA
  74.     if (dbgdlta) {
  75.         printf(" GetDPAnimChunk , vers = %d, nframes = %d, flags = %d \n",
  76.                dpAnimChnk.version, dpAnimChnk.nframes, dpAnimChnk.flags);
  77.     }
  78. #endif
  79.     return (iffp);
  80. }
  81.  
  82.  
  83. /*--------------------------------------------------------------*/
  84. /*- Write out a DPAN chunk                              -----------*/
  85. /*--------------------------------------------------------------*/
  86. IFFP PutDPAN(context)
  87. GroupContext *context;
  88. {
  89.     DPAnimChunk dpAnCh;
  90.  
  91.     setmem(&dpAnCh, sizeof(DPAnimChunk), 0);
  92.     dpAnCh.version = DPANIM_VERS3;
  93.     if (isAnimBrIO) {
  94.         dpAnCh.nframes = curAnimBr.nCels;
  95.         dpAnCh.duration = curAnimBr.duration;
  96.         dpAnCh.flags = curAnimBr.flags;
  97.         dpAnCh.rate = 0;
  98.     }
  99. #if 0    /* Not supporting anims, just animbrushes. */
  100.     else {
  101.         dpAnCh.nframes = nSave;
  102.         dpAnCh.rate = curfps;
  103.     }
  104. #endif
  105.     ByteFlipAnimChunk(&dpAnCh);
  106.     return
  107.         PutCk(context, ID_DPAN, (LONG) sizeof(DPAnimChunk), (BYTE *) & dpAnCh);
  108.     /* NOTE: needn't flip back to IBM byte-order, since not using further. */
  109. }
  110.  
  111. #if ANIMDISK
  112. /*--------------------------------------------------------------*/
  113. /* Anim file IO                                                    */
  114. /*--------------------------------------------------------------*/
  115. typedef char FileName[FILENAME_LENGTH + 1];
  116. extern WORD curFrame;
  117.  
  118. /*---------------------------------------------------------------*/
  119. /* Saving anim as separate ILBM's                                  */
  120. /*                                                               */
  121. /* Assumes <name> contains the desired file extension and that   */
  122. /* 1 <= start <= animFrames, 1 <= end <= animFrames              */
  123. /*---------------------------------------------------------------*/
  124. void SaveAnimAsILBMs(name, start, end)
  125. char *name;
  126. SHORT start, end;
  127. {
  128.     auto int i, len;
  129.     auto int nframes = end - start + 1;
  130.     FileName nm, bsname;
  131.     auto char nstr[SEQUENCE_SUFFIX_LENGTH], ext[FILENAME_SUFFIX_LENGTH + 2];
  132.     auto struct stat filestat;
  133.     auto char *ptr;
  134.     auto BOOL overwrite = NO;
  135.  
  136.         /* seperate out the file extension, if any */
  137.     strcpy(bsname, name);
  138.     ptr = strchr(bsname, '.');
  139.     if (ptr) {
  140.         strncpy(ext, ptr, sizeof(ext));
  141.         ext[sizeof(ext) - 1] = *ptr = '\0';
  142.     } else
  143.         ext[0] = '\0';
  144.  
  145.     len = strlen(bsname);
  146.     if (!len) {
  147.         NotAcceptableFileNameMsg();
  148.         return;
  149.     }
  150.     if ((len + SEQUENCE_SUFFIX_LENGTH) > FILENAME_ROOT_LENGTH) {
  151.         BaseNameTooLongMsg();
  152.         return;
  153.     }
  154.     AnimGoTo(start);
  155.     for (i = 0; i < nframes; i++) {
  156.         strcpy(nm, bsname);
  157.         num_to_string_zeroes(curFrame, nstr, SEQUENCE_SUFFIX_LENGTH);
  158.         strcat(nm, nstr);
  159.         strcat(nm, ext);
  160.         if (stat(nm, &filestat) != -1) {
  161.             if (filestat.st_mode & S_IFDIR) {
  162.                 CantReplaceDirMsg();
  163.                 break;
  164.             } else if (!(filestat.st_mode & S_IWRITE)) {
  165.                 FileIsWriteProtectedMsg();
  166.                 break;
  167.             } else if (!overwrite) {
  168.                 if (!ReplaceSequence(nm))
  169.                     break;
  170.                 else
  171.                     overwrite = YES;
  172.             }
  173.         }
  174.         if (!save_picture0(nm))
  175.             break;
  176.         AnimStepPage(1);
  177.         if (CheckAbort()) {
  178.             ClearAbortFlag();
  179.             break;
  180.         }
  181.     }
  182. }
  183.  
  184. #endif    /* ANIMDISK */
  185.  
  186.  
  187. /*--------------------------------------------------------------*/
  188. /* Loading ILBMs as Anim                                         */
  189. /* tries to load a sequence of ilbm files (bname...bname+num-1) */
  190. /* as a new anim with <num> frames.                                */
  191. /*--------------------------------------------------------------*/
  192. extern char **filename_strings;
  193. extern char pict_dir[], dir_mark[];
  194.  
  195. LoadILBMsAsAnim(char *bname, SHORT num, BOOL insert, char *pictExtension)
  196. {
  197.     int i, starti, endi, off;
  198.     char *fname;
  199.     LIST list;
  200.  
  201. #if 1    /* Prepare filenames */
  202.     set_full_directory(pict_dir);
  203.     setmem(&list, sizeof(LIST), 0);
  204.     if (!AllocFilenameStrings())
  205.         goto bail;
  206.     NewNames0(&list, pictExtension, FALSE);
  207. #endif
  208.  
  209.     off = strlen(dir_mark);
  210.     starti = -1;
  211.     for (i = 0; i < list.num_items; i++) {
  212.         fname = filename_strings[i] + off;
  213.         if (strcmp(fname, bname) == 0) {
  214.             starti = i;
  215.             break;
  216.         }
  217.     }
  218.     if (starti == -1)
  219.         goto bail;
  220.     endi = starti + num - 1;
  221.     endi = MIN(endi, list.num_items - 1);
  222.     num = endi - starti + 1;
  223.  
  224.     if (insert) {
  225.         /* insert pages after curFrame */
  226.         if (AddPages(num) == FAIL)
  227.             return;
  228.         AnimStepPage(1);        /* go to first newly added frame */
  229.     } else {
  230.         FreeStrings(&list);        /* Make room for NewAnim/SaveAnim dialog. */
  231.         FreeFilenameStrings();
  232.         /* create a new untitled anim with the appropriate # of frames */
  233.         if (NewAnim00(TRUE, num, TRUE) == FAIL)
  234.             return;                /* couldn't create new anim or user aborted */
  235. #if 1    /* Prepare filenames */
  236.         set_full_directory(pict_dir);
  237.         setmem(&list, sizeof(LIST), 0);
  238.         if (!AllocFilenameStrings())
  239.             goto bail;
  240.         NewNames0(&list, pictExtension, FALSE);
  241. #endif
  242.     }
  243.  
  244.     HideControls();
  245.     ZZZCursor();
  246.     for (i = starti; i <= endi; i++) {
  247.         fname = filename_strings[i];
  248.         if (fname[0] == dir_mark[0]) {
  249.             DelPages(1);        /* But suppose many pages left unfilled? */
  250.             break;                /* TBD: want to continue to find more
  251.                                  * dir's? */
  252.         }
  253.         fname += off;
  254.  
  255.         if (!load_picture00(fname, TRUE, TRUE))
  256.             break;
  257.  
  258. #if comingSoon
  259.         ...remap picture(avoid doing on first picture, when getting
  260.                          palette from first picture ?)
  261.             CopyPaletteFromFile(curpal, oldPaletteFileLetter);
  262. #endif
  263.  
  264.         if (CheckAbort()) {
  265.             ClearAbortFlag();
  266.             break;
  267.         }
  268.         AnimStepPage(1);
  269.     }
  270.     AnimGoTo(FIRST_FRAME_N);
  271.     UnZZZCursor();
  272.     ShowControls();
  273. bail:
  274.     FreeStrings(&list);
  275.     FreeFilenameStrings();
  276. }
  277.  
  278.  
  279. /* --------------- Set/Clear AnBrIO ---------------
  280.  */
  281. SetAnBrIO()
  282. {
  283.     isAnimBrIO = YES;
  284. }
  285.  
  286. ClearAnBrIO()
  287. {
  288.     isAnimBrIO = NO;
  289. }
  290.  
  291.  
  292. /*--------------------------------------------------------------*/
  293. /* Anim IFF IO routines                                            */
  294. /*--------------------------------------------------------------*/
  295.  
  296. #if 0
  297. SHORT animLoadState;
  298.  
  299. local void SetAnimLoadFail()
  300. {
  301.     animLoadState = FAIL;
  302. }
  303.  
  304. #endif    /* 0 */
  305.  
  306.  
  307. #define IFF_MEMFAIL -10
  308.  
  309. IFFP AnimGetDLTA(context, bmHdr, animHdr, frameCnt, buffer, bufsize)
  310. GroupContext *context;
  311. BitMapHeader *bmHdr;
  312. AnimHdr *animHdr;
  313. SHORT frameCnt;
  314. BYTE *buffer;
  315. LONG bufsize;
  316. {
  317.     IFFP iffp;
  318.     BITMAP *tmp;
  319.     int res;
  320.  
  321.     if (isAnimBrIO)
  322.         return (GetAnBrDLTA(context, bmHdr, animHdr, frameCnt, buffer, bufsize));
  323. #if 1
  324.     BugExit("AN1");
  325.             /* "IFF format for Anim only implemented for brush so far"); */
  326. #else    /* screen anim */
  327.     if (frameCnt == 1) {
  328.         animLoadState = SUCCESS;
  329.         if (loadStart > 0) {
  330. #if 0    /* TBD !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
  331.             if (AnimOp(ANIM_SAVECHGS) == FAIL)
  332.                 return (IFF_MEMFAIL);
  333. #endif
  334.         } else
  335.             AnimClearDirty();
  336.         if (animHdr->interleave != 0 && animHdr->interleave != 2) {
  337.             NotValidAnimMsg();
  338. #if 0    /* TBD: Not moved over from Amiga.  1/30/90 */
  339.             SkipErrorMsg();        /* tell dpio not to put another error req.
  340.                                  * up */
  341. #endif
  342.             return (BAD_FORM);
  343.         }
  344. #if 0    /* TBD: Not moved over from Amiga.  1/30/90 */
  345.         ShowLoadedPalette();
  346. #endif
  347.     }
  348.     if (CheckAbort()) {
  349.         ClearAbortFlag();
  350.         return (IFF_DONE);
  351.     }
  352.     if (dpAnimChnk.version > DPANIM_VERS1) {
  353.         if (frameCnt >= dpAnimChnk.nframes) {
  354.             /* Skip remaining deltas: they are for circular play */
  355. #if 0    /* TBD: Not moved over from Amiga.  1/30/90 */
  356.             /* TBD: Not an error !!!!!! */
  357.             SkipErrorMsg();        /* tell dpio not to put an error req. up */
  358. #endif
  359.             return (IFF_DONE);
  360.         }
  361.     }
  362. #if 0    /* TBD !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
  363.     res = (*animOps[ANIM_GETDLTA])(context, bmHdr, animHdr, frameCnt, buffer, bufsize);
  364. #endif    /* 0 */
  365.  
  366.     return (res);
  367. #endif    /* screen anim */
  368. }
  369.  
  370.  
  371. IFFP AnimPutDLTAs(context, buffer, bufsize)
  372. GroupContext *context;
  373. BYTE *buffer;
  374. LONG bufsize;
  375. {
  376.     if (isAnimBrIO)
  377.         return (PutAnBrDLTAs(context, buffer, bufsize));
  378. #if 1
  379.     else
  380.         return CLIENT_ERROR;    /* Not ready to handle Anim yet. */
  381. #else
  382.     else
  383.         return ((*animOps[ANIM_PUTDLTAS])(context, buffer, bufsize));
  384. #endif    /* 0 */
  385. }
  386.  
  387.  
  388. #if 0
  389. IFFP AnimIFFDone()
  390. {
  391.     SHORT res = IFF_DONE;
  392.  
  393.     if (isAnimBrIO)
  394.         return (AnBrIFFDone());
  395.     else {
  396.         if (dpAnimChnk.rate > 0)
  397.             SetRateFPS(dpAnimChnk.rate);
  398.         res = (*animOps[ANIM_IFF_DONE])();
  399.         if (animLoadState == FAIL)
  400.             AnimLoadFailMsg();
  401.         return (res);
  402.     }
  403. }
  404.  
  405. #endif    /* 0 */
  406.  
  407.  
  408. #if 0
  409. /*------------------------------------------------------------*/
  410. /* assume the bitmap the delta applies to is in dbm: read the */
  411. /*   Delta and apply it to dbm                                  */
  412. /*------------------------------------------------------------*/
  413. IFFP ReadAndApplyDelta(context, bmHdr, animHdr, dbm, buffer, bufsize)
  414. GroupContext *context;
  415. BitMapHeader *bmHdr;
  416. AnimHdr *animHdr;
  417. BITMAP *dbm;
  418. UBYTE *buffer;
  419. ULONG bufsize;
  420. {
  421.     int i, op, bpr;
  422.     ULONG iffp = 0;
  423.     ULONG ploffs[16];
  424.     ULONG planeSize[8], plast, plOffsSize;
  425.     SHORT depth = bmHdr->nPlanes;
  426.  
  427.     op = animHdr->operation;
  428.     if (op != ANIM_SHORTD && op != ANIM_RIFF && op != ANIM_RUNSKIP) {
  429.         NotValidAnimMsg();
  430.         return (IFF_DONE);
  431.     }
  432.     plOffsSize = (op == ANIM_SHORTD ? 32 : 64);
  433.  
  434.         /*--------------------------------------------------------
  435.          * NOTE: these ploffs are from the beginning of the chunk:
  436.          * the first one should have a value of 32 for short delta, 64 for riff,
  437.          * ?4? for ANIM_RUNSKIP.
  438.          */
  439.     iffp = IFFReadBytes(context, (BYTE *) ploffs, plOffsSize);
  440.     CheckIFFP();
  441.  
  442. #ifdef DBGDLTA
  443.     if (dbgdlta) {
  444.         printf("  planeOffsets = ");
  445.         for (i = 0; i < 8; i++)
  446.             printf(" %d | ", ploffs[i]);
  447.         printf("\n");
  448.     }
  449. #endif
  450.  
  451.     /* Compute Size of the compressed planes */
  452.     /* NOTE: ploffs[i] = 0 means no changes for that plane */
  453.  
  454.     plast = ChunkMoreBytes(context) + plOffsSize;
  455.     setmem(planeSize, 8 * sizeof(LONG), 0);
  456.     for (i = depth - 1; i >= 0; i--) {
  457.         if (ploffs[i]) {
  458.             planeSize[i] = plast - ploffs[i];
  459.             plast = ploffs[i];
  460.         }
  461.     }
  462. #ifdef DBGDLTA
  463.     if (dbgdlta) {
  464.         printf("  planeSize = ");
  465.         for (i = 0; i < 8; i++)
  466.             printf(" %d | ", planeSize[i]);
  467.         printf("\n");
  468.     }
  469. #endif
  470.  
  471.  
  472.     bpr = dbm->width;
  473.     for (i = 0; i < depth; i++) {
  474.         if (planeSize[i] != 0) {
  475.             /* FOR NOW, ONLY READ PLANE IF IT ALL FITS INTO BUFFER */
  476.             if (planeSize[i] > bufsize) {
  477. #ifdef DBGDLTA
  478.                 InfoMessage("ReadAndApplyDLTA: plane too big", "for buffer");    /* ENGLISH */
  479. #endif
  480.                 continue;
  481.             }
  482.             iffp = IFFReadBytes(context, buffer, planeSize[i]);
  483.             if (iffp != IFF_OKAY) {
  484. #ifdef DBGDLTA
  485.                 InfoMessage(" ReadBytes error", " in ReadAndApplyDLTA");        /* ENGLISH */
  486. #endif
  487.                 return (iffp);
  488.             }
  489.             if (i < dbm->planes)
  490.                 switch (op) {
  491.                   case ANIM_SHORTD:
  492.                     DecodeDLTA(dbm->seg[i], buffer);
  493.                     break;
  494.                   case ANIM_RIFF:
  495.                     decode_vkplane(buffer, dbm->seg[i], bpr);
  496.                     break;
  497.                 }
  498.         }
  499.     }
  500.     return (IFF_OKAY);
  501. }
  502.  
  503. #endif    /* 0 */
  504.  
  505.  
  506. #if 0
  507. /*--------------------------------------------------------------*/
  508. /* This Computes the RIFF delta between two bitmaps, abm and      */
  509. /* bbm, and outputs it to the IFF stream                         */
  510. /*--------------------------------------------------------------*/
  511.  
  512. IFFP OutputRiffDelta(context, anhdr, abm, bbm, delbm)
  513. GroupContext *context;
  514. AnimHdr *anhdr;
  515. BITMAP *abm, *bbm;        /* two bitmaps to be compared */
  516. BITMAP *delbm;    /* contains the resulting delta planes */
  517. {
  518.     ULONG sizes[8];
  519.     IFFP ifferror = 0;
  520.     int i;
  521.     SHORT bpr = abm->width;
  522.  
  523.     for (i = 0; i < abm->planes; i++)
  524.         sizes[i] = MkRIFF(abm->seg[i], bbm->seg[i], delbm->seg[i],
  525.                           abm->Rows, bpr, bpr);
  526.     ifferror = WriteDelta(context, anhdr, delbm->seg, sizes);
  527.     return (ifferror);
  528. }
  529.  
  530. #endif    /* 0 */
  531.